package com.dinghui.pay.controller.union;

import com.dinghui.pay.common.ResponseResult;
import com.dinghui.pay.pojo.TbOrder;
import com.dinghui.pay.pojo.TbUser;
import com.dinghui.pay.pojo.param.ScanCodePayOrderParam;
import com.dinghui.pay.service.OrderService;
import com.dinghui.pay.service.UserService;
import com.dinghui.pay.utils.JwtUtils;
import com.dinghui.pay.utils.RedisUtils;
import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.SDKConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0
 * @author: trt
 * @description:
 * @create: 2021-06-05 19:46
 */
// 银联付款码 业务接口
@RestController
@RequestMapping("/api/union/scanCode")
public class ScanCodeController {

    @Autowired
    private SDKConfig config;

    @Autowired
    private AcpService acpService;

    @Value("${unionpay.mch-id}")
    private String mchId;

    @Value("${unionpay.frontUrl}")
    private String frontUrl;

    @Value("${unionpay.backUrl}")
    private String backUrl;

    @Value("${unionpay.orderUrl}")
    private String orderUrl;

    @Value("${unionpay.wapFrontUrl}")
    private String wapFrontUrl;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 创建支付订单
     *
     * 生成模拟付款码地址
     * https://open.unionpay.com/tjweb/tool/qrcodeFormPage/coverSweepReceiverApp
     *
     * 银联付款码规则必须是622开头的数字，一共19位数字组成 正则：^622[0-9]{16}$
     *
     * 二维码支付 接口：https://open.unionpay.com/tjweb/api/dictionary?apiSvcId=468
     * 二维码消费（被扫） https://open.unionpay.com/tjweb/acproduct/APIList?apiservId=468&acpAPIId=798&bussType=0
     *
     */
    // 付款码收款
    @PostMapping("/scanCodePayOrder")
    public ResponseResult scanCodePayOrder(@RequestBody ScanCodePayOrderParam param, @RequestHeader HashMap header) {
        String token = header.get("token").toString();
        Long userId = Long.parseLong(jwtUtils.getClaimByToken(token).getSubject());
        int orderId = param.getOrderId();
        TbUser user = new TbUser();
        user.setUserId(userId);
        long count = userService.getCount(user);
        //判断用户是否存在
        if (count == 0) {
            return ResponseResult.error("用户不存在");
        }

        //判断用户是否拥有这个订单，并且订单是未支付状态
        TbOrder order = new TbOrder();
        order.setUserId(userId.intValue());
        order.setId(orderId);
        order.setStatus(1);
        count = orderService.getCount(order);
        if (count == 0) {
            return ResponseResult.error("不是有效的订单");
        }

        // todo 验证购物券是否有效
        // todo 验证团购活动是否有效

        //查询订单详情信息
        order = new TbOrder();
        order.setId(orderId);
        order = orderService.getOne(order); //订单对象
        String amount = order.getAmount().multiply(new BigDecimal("100")).intValue() + "";

        try {
            Map<String, String> contentData = new HashMap<String, String>();
            contentData.put("version", "5.0.0");  //版本号 全渠道默认值
            contentData.put("encoding", "UTF-8"); //字符集编码 可以使用UTF-8,GBK两种方式
            contentData.put("signMethod", "01"); //签名方法
            contentData.put("txnType", "01");    //交易类型 01:消费
            contentData.put("txnSubType", "06");   //交易子类 06：二维码消费
            contentData.put("bizType", "000000");  //填写000000
            contentData.put("channelType", "08");  //渠道类型 08手机
            contentData.put("merId", mchId);   //商户号码
            contentData.put("accessType", "0");  //接入类型，商户接入填0 ，不需修改
            contentData.put("orderId", order.getCode());    //商户订单号
            //订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
            contentData.put("txnTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
            contentData.put("txnAmt", amount);   //交易金额
            contentData.put("currencyCode", "156"); //境内商户固定 156 人民币
            contentData.put("qrNo", param.getAuthCode());   //C2B码,1-20位数字 付款码
            contentData.put("termId", "49000002");  //终端号 49000002案例，不可随便写
            contentData.put("backUrl", backUrl);

            Map<String, String> reqData = acpService.sign(contentData,"UTF-8");
            String requestAppUrl = config.getBackRequestUrl();
            //发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）
            Map<String, String> rspData = AcpService.post(reqData,requestAppUrl,"UTF-8");

            if(!rspData.isEmpty()){
                if(acpService.validate(rspData, "UTF-8")){
                    String respCode = rspData.get("respCode") ;
                    if(("00").equals(respCode)){
                        //更新本地商品订单信息，但是不更新商品订单状态
                        String queryId=rspData.get("queryId");
                        order.setPrepayId(queryId);
                        order.setStatus(2);
                        order.setPaymentType(3); //支付类型
                        order.setId(order.getId());  // 查询条件
                        orderService.update(order);
                        return ResponseResult.success("付款成功");
                    }else{
                        return ResponseResult.error("付款失败");
                    }

                }else{
                    return ResponseResult.error("付款失败");
                }
            }else{
                return ResponseResult.error("付款失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error("付款失败");
        }
    }



}